package com.xyht.sca_s.student_manage_system.modules.advanceRegistration.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xyht.sca_s.student_manage_system.auth.entity.Node;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.modules.advanceRegistration.entity.RxAdvanceRegistrationOrg;
import com.xyht.sca_s.student_manage_system.modules.advanceRegistration.entity.req.RxAdvanceRegistrationOrgReq;
import com.xyht.sca_s.student_manage_system.modules.advanceRegistration.entity.resp.RxAdvanceRegistrationOrgExportResp;
import com.xyht.sca_s.student_manage_system.modules.advanceRegistration.entity.resp.RxAdvanceRegistrationOrgResp;
import com.xyht.sca_s.student_manage_system.modules.advanceRegistration.mapper.RxAdvanceRegistrationOrgMapper;
import com.xyht.sca_s.student_manage_system.modules.advanceRegistration.service.RxAdvanceRegistrationOrgService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTask;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTaskDetail;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskMapper;
import com.xyht.sca_s.student_manage_system.modules.dormitory.entity.SmsDormitory;
import com.xyht.sca_s.student_manage_system.modules.dormitory.entity.SmsDormitoryBed;
import com.xyht.sca_s.student_manage_system.modules.dormitory.entity.resp.SmsDormitoryInfoExportResp;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgStructure;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskDetailReason.*;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskNameExample.TASK_NAME_ADVANCE_REGISTRATION_ORG_IMPORT;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskNameExample.TASK_NAME_DORMITORY_OWNERSHIP_IMPORT;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskStatus.TASK_STATUS_DONE;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskStatus.TASK_STATUS_ERR;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskTypeConstant.TASK_TYPE_ADVANCE_REGISTRATION_ORG_IMPORT;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskTypeConstant.TASK_TYPE_DORMITORY_OWNERSHIP;
import static com.xyht.sca_s.student_manage_system.modules.dormitory.constant.IsStuConstant.*;

/**
 * <p>
 * 预报名组织架构 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2024-04-10
 */
@Service
public class RxAdvanceRegistrationOrgServiceImpl extends ServiceImpl<RxAdvanceRegistrationOrgMapper, RxAdvanceRegistrationOrg> implements RxAdvanceRegistrationOrgService {

    @Resource
    private RxAdvanceRegistrationOrgMapper rxAdvanceRegistrationOrgMapper;
    @Resource
    private SmsImportTaskMapper smsImportTaskMapper;
    @Resource
    SmsImportTaskDetailMapper smsImportTaskDetailMapper;
    @Resource
    PlatformTransactionManager transactionManager;
    @Override
    @Async
    public Future<ResponseResult> batchAdvanceRegistrationOrg(Map<String, Object> map, String user_id) {
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(map));
        List<RxAdvanceRegistrationOrgExportResp> respList = JSONObject.parseArray(JSON.toJSONString(jsonObject.get("list")), RxAdvanceRegistrationOrgExportResp.class);
        if (respList == null || respList.size() < 1) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }

        //创建导入任务
        SmsImportTask smsImportTask = new SmsImportTask();
        smsImportTask.setTaskName(TASK_NAME_ADVANCE_REGISTRATION_ORG_IMPORT);
        smsImportTask.setUserId(user_id);
        smsImportTask.setTaskType(TASK_TYPE_ADVANCE_REGISTRATION_ORG_IMPORT);
        smsImportTaskMapper.insert(smsImportTask);
        batchAddAdvanceRegistrationOrg(respList, smsImportTask.getId(),user_id);
        return new AsyncResult<>(CommonResult.success());
    }

    private void batchAddAdvanceRegistrationOrg( List<RxAdvanceRegistrationOrgExportResp> exportBatchReqs, String id,String userId) {

        int OFFSET_ROW = 1;
        int task_status = TASK_STATUS_DONE;
        for (int i = 0; i < exportBatchReqs.size(); i++) {
            //开启事务
            DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
            // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
            dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 设置嵌套事务
            TransactionStatus status = transactionManager.getTransaction(dt);
            try {
                RxAdvanceRegistrationOrgExportResp storage = exportBatchReqs.get(i);
                if (isNullOrEmpty(storage.getMajorName())){
                    continue;
                }

                List<RxAdvanceRegistrationOrg> orgMajorNameList = rxAdvanceRegistrationOrgMapper.selectList(new LambdaQueryWrapper<RxAdvanceRegistrationOrg>()
                        .eq(RxAdvanceRegistrationOrg::getMajorName, storage.getMajorName()));
                if (orgMajorNameList != null && orgMajorNameList.size() > 0) {
                    transactionManager.rollback(status);
                    task_status = TASK_STATUS_ERR;
                    createTeacherImportTaskDetail(id, REASON_ADVANCE_REGISTRATION_ORG_DUPLICATION, (i + OFFSET_ROW) + "");
                    continue;
                }
                RxAdvanceRegistrationOrg rxAdvanceRegistrationOrg = new RxAdvanceRegistrationOrg();
                rxAdvanceRegistrationOrg.setMajorName(storage.getMajorName());
                rxAdvanceRegistrationOrgMapper.insert(rxAdvanceRegistrationOrg);
                transactionManager.commit(status);
            } catch (Exception e) {
                transactionManager.rollback(status);
                task_status = TASK_STATUS_ERR;
                createTeacherImportTaskDetail(id, REASON_IMPORT_ERR, (i + OFFSET_ROW) + "");
            } finally {
                if (status.isNewTransaction() && !status.isCompleted()) {
                    transactionManager.commit(status);
                }
            }
        }

        SmsImportTask smsImportTask = new SmsImportTask();
        smsImportTask.setId(id);
        smsImportTask.setStatus(task_status);
        smsImportTaskMapper.updateById(smsImportTask);
    }

    private void createTeacherImportTaskDetail(String id, String reason, String row) {
        SmsImportTaskDetail smsImportTaskDetail = new SmsImportTaskDetail();
        smsImportTaskDetail.setTaskId(id);
        smsImportTaskDetail.setFailReason(reason);
        smsImportTaskDetail.setFailRow(row);
        smsImportTaskDetailMapper.insert(smsImportTaskDetail);
    }
    @Override
    public ResponseResult addAdvanceRegistrationOrg(RxAdvanceRegistrationOrgReq addReq, String userId) {
        if (isNullOrEmpty(addReq.getMajorName())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        List<RxAdvanceRegistrationOrg> orgMajorNameList = rxAdvanceRegistrationOrgMapper.selectList(new LambdaQueryWrapper<RxAdvanceRegistrationOrg>()
                .eq(RxAdvanceRegistrationOrg::getMajorName, addReq.getMajorName()));
        if (orgMajorNameList != null && orgMajorNameList.size() > 0) {
            return CommonResult.failed(CommonCodeEnum.ADVANCE_REGISTRATION_ORG_DUPLICATE);
        }
//        List<RxAdvanceRegistrationOrg> orgCodeList = rxAdvanceRegistrationOrgMapper.selectList(new LambdaQueryWrapper<RxAdvanceRegistrationOrg>()
//                .eq(RxAdvanceRegistrationOrg::getOrgCode, addReq.getOrgCode()));
//        if (orgCodeList != null && orgCodeList.size() > 0) {
//            return CommonResult.failed(CommonCodeEnum.ADVANCE_REGISTRATION_ORG_DUPLICATE);
//        }
        RxAdvanceRegistrationOrg advanceRegistrationOrg = new RxAdvanceRegistrationOrg();
        BeanUtils.copyProperties(addReq, advanceRegistrationOrg);
        advanceRegistrationOrg.setUserId(userId);
        rxAdvanceRegistrationOrgMapper.insert(advanceRegistrationOrg);
        return CommonResult.success();
    }

    @Override
    public ResponseResult deletedAdvanceRegistrationOrg(RxAdvanceRegistrationOrgReq deletedReq) {
        if (isNullOrEmpty(deletedReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        RxAdvanceRegistrationOrg advanceRegistrationOrg = rxAdvanceRegistrationOrgMapper.selectById(deletedReq.getId());
        if (isNullOrEmpty(advanceRegistrationOrg)) {
            return CommonResult.failed(CommonCodeEnum.ADVANCE_REGISTRATION_ORG_NOT_EXIST);
        }
        rxAdvanceRegistrationOrgMapper.deleteById(deletedReq.getId());
        return CommonResult.success();
    }

    @Override
    public ResponseResult updateAdvanceRegistrationOrg(RxAdvanceRegistrationOrgReq updateReq) {
        if (isNullOrEmpty(updateReq.getId(),updateReq.getMajorName())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        RxAdvanceRegistrationOrg advanceRegistrationOrg = rxAdvanceRegistrationOrgMapper.selectById(updateReq.getId());
        if (isNullOrEmpty(advanceRegistrationOrg)) {
            return CommonResult.failed(CommonCodeEnum.ADVANCE_REGISTRATION_ORG_NOT_EXIST);
        }
        List<RxAdvanceRegistrationOrg> orgMajorNameList = rxAdvanceRegistrationOrgMapper.selectList(new LambdaQueryWrapper<RxAdvanceRegistrationOrg>()
                .ne(RxAdvanceRegistrationOrg::getId, updateReq.getId())
                .eq(RxAdvanceRegistrationOrg::getMajorName, updateReq.getMajorName()));
        if (orgMajorNameList != null && orgMajorNameList.size() > 0) {
            return CommonResult.failed(CommonCodeEnum.ADVANCE_REGISTRATION_ORG_DUPLICATE);
        }
//        List<RxAdvanceRegistrationOrg> orgCodeList = rxAdvanceRegistrationOrgMapper.selectList(new LambdaQueryWrapper<RxAdvanceRegistrationOrg>()
//                .ne(RxAdvanceRegistrationOrg::getId, updateReq.getId())
//                .eq(RxAdvanceRegistrationOrg::getOrgCode, updateReq.getOrgCode()));
//        if (orgCodeList != null && orgCodeList.size() > 0) {
//            return CommonResult.failed(CommonCodeEnum.ADVANCE_REGISTRATION_ORG_DUPLICATE);
//        }
        BeanUtils.copyProperties(updateReq, advanceRegistrationOrg);
        rxAdvanceRegistrationOrgMapper.updateById(advanceRegistrationOrg);
        return CommonResult.success();
    }

    @Override
    public ResponseResult getAdvanceRegistrationOrgList(Integer pageNum, Integer pageSize, String searchStr) {
        Page<RxAdvanceRegistrationOrg> page = new Page<>(pageNum,pageSize);
        LambdaQueryWrapper<RxAdvanceRegistrationOrg> lambdaQueryWrapper = new LambdaQueryWrapper<RxAdvanceRegistrationOrg>().orderByDesc(RxAdvanceRegistrationOrg::getCreateTime);
        if (!isNullOrEmpty(searchStr)) {
            lambdaQueryWrapper.and(i ->
                    i.like(RxAdvanceRegistrationOrg::getMajorName, searchStr)
                    .or()
                    .like(RxAdvanceRegistrationOrg::getOrgName, searchStr)
                    .or()
                    .like(RxAdvanceRegistrationOrg::getOrgCode, searchStr));
        }
        rxAdvanceRegistrationOrgMapper.selectPage(page, lambdaQueryWrapper);
        List<RxAdvanceRegistrationOrgResp> advanceRegistrationOrgList = page.getRecords()
                .stream()
                .map(advanceRegistrationOrg -> {
                    RxAdvanceRegistrationOrgResp advanceRegistrationOrgResp = new RxAdvanceRegistrationOrgResp();
                    BeanUtils.copyProperties(advanceRegistrationOrg,advanceRegistrationOrgResp);
                    return advanceRegistrationOrgResp;
                })
                .collect(Collectors.toList());
        return CommonResult.success(advanceRegistrationOrgList, (int) page.getTotal());
    }
}
